package org.jeecg.modules.wmhb.controller;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.UserConstant;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.SysDepartModel;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.wmhb.entity.WmProductRecpt;
import org.jeecg.modules.wmhb.entity.WmTask;
import org.jeecg.modules.wmhb.entity.WmTaskbook;
import org.jeecg.modules.wmhb.service.IWmProductRecptService;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;

import org.jeecg.modules.wmhb.service.IWmTaskLogService;
import org.jeecg.modules.wmhb.service.IWmTaskService;
import org.jeecg.modules.wmhb.service.IWmTaskbookService;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.jeecg.common.system.base.controller.JeecgController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSON;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.apache.shiro.authz.annotation.RequiresPermissions;

/**
 * @Description: 任务报工入库
 * @Author: jeecg-boot
 * @Date: 2024-08-31
 * @Version: V1.0
 */
@Api(tags = "任务报工入库")
@RestController
@RequestMapping("/wmhb/wmProductRecpt")
@Slf4j
public class WmProductRecptController extends JeecgController<WmProductRecpt, IWmProductRecptService> {
    @Autowired
    private IWmProductRecptService wmProductRecptService;
    @Autowired
    private IWmTaskService wmTaskService;
    @Autowired
    private IWmTaskbookService wmTaskbookService;
    @Autowired
    ISysBaseAPI sysBaseApi;
    @Autowired
    private IWmTaskLogService wmTaskLogService;

    /**
     * 添加
     *
     * @param wmProductRecpt
     * @return
     */
    @AutoLog(value = "任务报工入库-添加")
    @ApiOperation(value = "任务报工入库-添加", notes = "任务报工入库-添加")
    @RequiresPermissions("wmhb:wm_product_recpt:add")
    @PostMapping(value = "/add")
    @Transactional
    public Result<String> add(@RequestBody WmProductRecpt wmProductRecpt) {
        if(wmProductRecpt.getCompleteQuantity() <= 0){
            return Result.error("报工数量必须大于0");
        }
        WmTask wmTask = wmTaskService.getById(wmProductRecpt.getWmTaskId());
        List<String> statusList = new ArrayList<>();
        if (!wmTask.getStatus().equals(UserConstant.TASK_STATUS_PRODUCING)) {
            throw new RuntimeException("当前状态不能报工");
        }

        //获取所有子任务(包括自己)
        List<WmTask> wmTaskList = wmTaskService.getChildrenAsOneList(wmTask);
        statusList.add(UserConstant.TASK_STATUS_PRODUCED);
        statusList.add(UserConstant.TASK_STATUS_SALED);
        statusList.add(UserConstant.TASK_STATUS_WAIT_DEBUG);
        statusList.add(UserConstant.TASK_STATUS_DEBUGING);
        statusList.add(UserConstant.TASK_STATUS_DEBUGED);
        statusList.add(UserConstant.TASK_STATUS_ARRIVED);
        statusList.add(UserConstant.TASK_STATUS_FINISHED);
        Double newCompleteNum = wmProductRecpt.getCompleteQuantity() + wmTask.getCompleteNum();
        Double remainNum = wmTask.getQuantity() - newCompleteNum;
        if (newCompleteNum > wmTask.getQuantity()) {
            throw new RuntimeException("报工数量不能大于设计数量");
        }

        //保存报工记录
        wmProductRecpt.setRemainQuantity(remainNum);
        //获取事业部信息
        SysDepartModel sysDepartModel = sysBaseApi.selectAllById(wmTask.getBuId());
        if(wmTask.getType().equals(UserConstant.TASK_TYPE_SELF) && !StringUtils.isEmpty(sysDepartModel.getProductWarehouseId())) {
            wmProductRecpt.setWarehouseId(sysDepartModel.getProductWarehouseId());
        }
        else if(wmTask.getType().equals(UserConstant.TASK_TYPE_BUY) && !StringUtils.isEmpty(sysDepartModel.getVendorWarehouseId())) {
            wmProductRecpt.setWarehouseId(sysDepartModel.getVendorWarehouseId());
        }
        else if(wmTask.getType().equals(UserConstant.TASK_TYPE_OUT) && !StringUtils.isEmpty(sysDepartModel.getOutSourceWarehouseId())) {
            wmProductRecpt.setWarehouseId(sysDepartModel.getOutSourceWarehouseId());
        }
        wmProductRecptService.save(wmProductRecpt);

        if (wmTask.getQuantity().equals(newCompleteNum)) {
            //如果数量达到报工完成，需要判断子任务是否还有在生产状态，如果有则不能报工完成
            for(WmTask wmTaskItem: wmTaskList){
                if(!statusList.contains(wmTaskItem.getStatus()) && !wmTaskItem.getId().equals(wmTask.getId())){
                    //throw new RuntimeException("当前任务有未生产完成的子任务");
                }

                //子任务生产完毕
                if(!wmTaskItem.getId().equals(wmTask.getId())){
                    wmTaskItem.setStatus(UserConstant.TASK_STATUS_PRODUCED);//生产完毕
                    wmTaskItem.setProgress("60");//生产完成算60%
                    wmTaskItem.setCompleteNum(wmTaskItem.getQuantity());
                    wmTaskService.updateById(wmTaskItem);

                    //新增报工记录(子任务)
                    WmProductRecpt wmProductRecptChild = new WmProductRecpt();
                    wmProductRecptChild.setWmTaskId(wmTaskItem.getId());
                    wmProductRecptChild.setCompleteQuantity(wmTaskItem.getQuantity() - wmTaskItem.getCompleteNum());
                    wmProductRecptChild.setRemainQuantity(0D);
                    wmProductRecptChild.setBomRecptPercent("0");
                    wmProductRecptChild.setNotCompletePercent("0");
                    if(wmTaskItem.getType().equals(UserConstant.TASK_TYPE_SELF) && !StringUtils.isEmpty(sysDepartModel.getProductWarehouseId())) {
                        wmProductRecptChild.setWarehouseId(sysDepartModel.getProductWarehouseId());
                    }
                    else if(wmTaskItem.getType().equals(UserConstant.TASK_TYPE_BUY) && !StringUtils.isEmpty(sysDepartModel.getVendorWarehouseId())) {
                        wmProductRecptChild.setWarehouseId(sysDepartModel.getVendorWarehouseId());
                    }
                    else if(wmTaskItem.getType().equals(UserConstant.TASK_TYPE_OUT) && !StringUtils.isEmpty(sysDepartModel.getOutSourceWarehouseId())) {
                        wmProductRecptChild.setWarehouseId(sysDepartModel.getOutSourceWarehouseId());
                    }
                    wmProductRecptService.save(wmProductRecptChild);
                }
            }

            wmTask.setStatus(UserConstant.TASK_STATUS_PRODUCED);//生产完毕
            wmTask.setProgress("60");//生产完成算60%

            //如果当前任务为根任务，任务书状态改为和根任务状态一致
            if(wmTask.getAncestors().equals(UserConstant.ANCESTOR_ZERO)) {
                WmTaskbook wmTaskbook = wmTaskbookService.getById(wmTask.getWmTaskbookId());
                wmTaskbook.setStatus(wmTask.getStatus());
                wmTaskbook.setProgress("60");//生产完成算60%
                wmTaskbookService.updateById(wmTaskbook);
            }

            //只有设计起点任务才更新报工日志
            if(wmTask.getIsStartPoint().equals(UserConstant.SYS_YES)) {
                //更新任务日志
                wmTaskLogService.updateTaskLog(wmTask.getId(), UserConstant.TASK_LOG_TYPE_PRODUCE);
            }
        }
        else{
            //处于列表里面状态的都可以报工，不在列表状态的不可以报工
            statusList.add(UserConstant.TASK_STATUS_PRODUCING);
            for(WmTask wmTaskItem: wmTaskList){
                if(!statusList.contains(wmTaskItem.getStatus()) && !wmTaskItem.getId().equals(wmTask.getId())){
                    throw new RuntimeException("当前任务有不在生产状态的子任务");
                }
            }
        }
        wmTask.setCompleteNum(newCompleteNum);
        wmTaskService.updateById(wmTask);

        //更新父任务为生产中状态(只要子任务在生产，父任务就当作是在生产)
        List<String> ancestorIdList = Arrays.asList(wmTask.getAncestors().split(","));
        for(String id: ancestorIdList){
            if(!id.equals("0")) {
                WmTask wmTaskAncestor = wmTaskService.getById(id);
                if(!statusList.contains(wmTaskAncestor.getStatus())){
                    wmTaskAncestor.setStatus(UserConstant.TASK_STATUS_PRODUCING);
                    wmTaskService.updateById(wmTaskAncestor);
                }
            }
        }

        return Result.OK("添加成功！");
    }

    /**
     * 编辑
     *
     * @param wmProductRecpt
     * @return
     */
    @AutoLog(value = "任务报工入库-编辑")
    @ApiOperation(value = "任务报工入库-编辑", notes = "任务报工入库-编辑")
    @RequiresPermissions("wmhb:wm_product_recpt:edit")
    @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
    @Transactional
    public Result<String> edit(@RequestBody WmProductRecpt wmProductRecpt) {
        WmTask wmTask = wmTaskService.getById(wmProductRecpt.getWmTaskId());

        //获取所有子任务(包括自己)
        List<WmTask> wmTaskList = wmTaskService.getChildrenAsOneList(wmTask);

        //获取事业部信息
        SysDepartModel sysDepartModel = sysBaseApi.selectAllById(wmTask.getBuId());
        if(wmTask.getType().equals(UserConstant.TASK_TYPE_SELF) && !StringUtils.isEmpty(sysDepartModel.getProductWarehouseId())) {
            wmProductRecpt.setWarehouseId(sysDepartModel.getProductWarehouseId());
        }
        else if(wmTask.getType().equals(UserConstant.TASK_TYPE_BUY) && !StringUtils.isEmpty(sysDepartModel.getVendorWarehouseId())) {
            wmProductRecpt.setWarehouseId(sysDepartModel.getVendorWarehouseId());
        }
        else if(wmTask.getType().equals(UserConstant.TASK_TYPE_OUT) && !StringUtils.isEmpty(sysDepartModel.getOutSourceWarehouseId())) {
            wmProductRecpt.setWarehouseId(sysDepartModel.getOutSourceWarehouseId());
        }

        WmProductRecpt wmProductRecptRecord = wmProductRecptService.getById(wmProductRecpt.getId());
        Double newCompleteNum = wmTask.getCompleteNum() - wmProductRecptRecord.getCompleteQuantity() + wmProductRecpt.getCompleteQuantity();
        Double remainNum = wmTask.getQuantity() - newCompleteNum;
        if (newCompleteNum > wmTask.getQuantity()) {
            throw new RuntimeException("数据异常");
        }
        else if (wmTask.getQuantity().equals(newCompleteNum)) {
            //如果数量达到报工完成，需要判断子任务是否还有在生产状态，如果有则不能报工完成
            for(WmTask wmTaskItem: wmTaskList){
                //子任务生产完毕
                if(!wmTaskItem.getId().equals(wmTask.getId())){
                    wmTaskItem.setStatus(UserConstant.TASK_STATUS_PRODUCED);//生产完毕
                    wmTaskItem.setProgress("60");//生产完成算60%
                    wmTaskItem.setCompleteNum(wmTaskItem.getQuantity());
                    wmTaskService.updateById(wmTaskItem);

                    //新增报工记录(子任务)
                    WmProductRecpt wmProductRecptChild = new WmProductRecpt();
                    wmProductRecptChild.setWmTaskId(wmTaskItem.getId());
                    wmProductRecptChild.setCompleteQuantity(wmTaskItem.getQuantity() - wmTaskItem.getCompleteNum());
                    wmProductRecptChild.setRemainQuantity(0D);
                    wmProductRecptChild.setBomRecptPercent("0");
                    wmProductRecptChild.setNotCompletePercent("0");
                    if(wmTaskItem.getType().equals(UserConstant.TASK_TYPE_SELF) && !StringUtils.isEmpty(sysDepartModel.getProductWarehouseId())) {
                        wmProductRecptChild.setWarehouseId(sysDepartModel.getProductWarehouseId());
                    }
                    else if(wmTaskItem.getType().equals(UserConstant.TASK_TYPE_BUY) && !StringUtils.isEmpty(sysDepartModel.getVendorWarehouseId())) {
                        wmProductRecptChild.setWarehouseId(sysDepartModel.getVendorWarehouseId());
                    }
                    else if(wmTaskItem.getType().equals(UserConstant.TASK_TYPE_OUT) && !StringUtils.isEmpty(sysDepartModel.getOutSourceWarehouseId())) {
                        wmProductRecptChild.setWarehouseId(sysDepartModel.getOutSourceWarehouseId());
                    }
                    wmProductRecptService.save(wmProductRecptChild);
                }
            }

            wmTask.setStatus(UserConstant.TASK_STATUS_PRODUCED);//生产完毕
            wmTask.setProgress("60");//生产完成算60%

            //如果当前任务为根任务，任务书状态改为和根任务状态一致
            if(wmTask.getAncestors().equals(UserConstant.ANCESTOR_ZERO)) {
                WmTaskbook wmTaskbook = wmTaskbookService.getById(wmTask.getWmTaskbookId());
                wmTaskbook.setStatus(wmTask.getStatus());
                wmTaskbook.setProgress("60");//生产完成算60%
                wmTaskbookService.updateById(wmTaskbook);
            }

            //只有设计起点任务才更新报工日志
            if(wmTask.getIsStartPoint().equals(UserConstant.SYS_YES)) {
                //更新任务日志
                wmTaskLogService.updateTaskLog(wmTask.getId(), UserConstant.TASK_LOG_TYPE_PRODUCE);
            }
        }
        else{
            wmTask.setStatus(UserConstant.TASK_STATUS_PRODUCING);//生产中
        }

        //更新任务
        wmTask.setCompleteNum(newCompleteNum);
        wmTaskService.updateById(wmTask);

        //更新报工信息
        wmProductRecpt.setRemainQuantity(remainNum);
        wmProductRecptService.updateById(wmProductRecpt);

        //更新父任务为生产中状态(只要子任务在生产，父任务就当作是在生产)
        List<String> ancestorIdList = Arrays.asList(wmTask.getAncestors().split(","));
        for(String id: ancestorIdList){
            if(!id.equals("0")) {
                WmTask wmTaskAncestor = wmTaskService.getById(id);
                wmTaskAncestor.setStatus(UserConstant.TASK_STATUS_PRODUCING);
                wmTaskService.updateById(wmTaskAncestor);
            }
        }

        return Result.OK("编辑成功!");
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    //@AutoLog(value = "任务报工入库-通过id查询")
    @ApiOperation(value = "任务报工入库-通过id查询", notes = "任务报工入库-通过id查询")
    @GetMapping(value = "/queryById")
    public Result<WmProductRecpt> queryById(@RequestParam(name = "id", required = true) String id) {
        WmProductRecpt wmProductRecpt = wmProductRecptService.getById(id);
        if (wmProductRecpt == null) {
            return Result.error("未找到对应数据");
        }
        return Result.OK(wmProductRecpt);
    }

    /**
     * 通过任务ID查询报工记录
     */
    @ApiOperation(value = "任务报工入库-通过任务ID查询报工记录", notes = "任务报工入库-通过任务ID查询报工记录")
    @GetMapping(value = "/queryListByWmTaskId")
    public Result<List<WmProductRecpt>> queryListByWmTaskId(String wmTaskId){
        List<WmProductRecpt> wmProductRecptList = wmProductRecptService.queryListByWmTaskId(wmTaskId);
        return Result.OK(wmProductRecptList);
    }
}
